////////////////////////////////////////////////////////////////////////////////
// Company:     SLCC
// Engineers:   Harvey Wilson
// Module name: vga_sync_hw2.v
// from vga_sync_hw.v revised 17 Aug 2009
// from vga_sync.v revised 27 May 2009
//
// RGB Output is the pre_RGB Input you want to display, with needed adjustments added.
// This revised module blanks RGB when needed, synchronizes RGB to p_tick
//
// Rev 17 Aug 2009
// Rev 10 Sep 2009 shifted down to show 1st line on LCD monitor
//   localparam VF = 22;  // v. front (top) border,  was 10
//
// Rev 02 Jan 10 make acceptable for F4.2
// replace localparam with parameter
// Rev 11 Jan 10 added items in sensitivity lists to avoid warnings
////////////////////////////////////////////////////////////////////////////////
//module vga_sync_hw2  // the following format is unusable in F4.2 (01 Jan 10)
//   (
//    input wire Master_clk, reset,
//    input wire [7:0] pre_RGB,
//    output reg [7:0] RGB,
//    output wire hsync, vsync, video_on, p_tick,
//    output wire [9:0] pixel_x, pixel_y
//   );
module vga_sync_hw2
   (Master_clk, reset, pre_RGB,
    RGB, hsync, vsync, video_on, p_tick, pixel_x, pixel_y
    );

    input        Master_clk, reset;
    input  [7:0] pre_RGB;
    output [7:0] RGB;
    reg    [7:0] RGB;
    output       hsync, vsync, video_on, p_tick;
    output [9:0] pixel_x, pixel_y;

   // constant declaration
   // VGA 640-by-480 sync parameters
   parameter HD = 640; // horizontal display area
   parameter HF = 48 ; // h. front (left) border
   parameter HB = 16 ; // h. back (right) border
   parameter HR = 96 ; // h. retrace
   parameter VD = 480; // vertical display area
   parameter VF = 22;  // v. front (top) border,  was 10
   parameter VB = 33;  // v. back (bottom) border
   parameter VR = 2;   // v. retrace

   // mod-2 counter
   reg mod2_reg;
   wire mod2_next;
   // sync counters
   reg [9:0] h_count_reg, h_count_next;
   reg [9:0] v_count_reg, v_count_next;
   // output buffer
   reg v_sync_reg, h_sync_reg;
   wire v_sync_next, h_sync_next;
   // status signal
   wire h_end, v_end, pixel_tick;

   // body
   // registers
//   always @(posedge Master_clk, posedge reset) // F4 not like comma
   always @(posedge Master_clk or posedge reset)
      if (reset)
         begin
            mod2_reg <= 1'b0;
            v_count_reg <= 0;
            h_count_reg <= 0;
            v_sync_reg <= 1'b0;
            h_sync_reg <= 1'b0;
         end
      else
         begin
            mod2_reg <= mod2_next;
            v_count_reg <= v_count_next;
            h_count_reg <= h_count_next;
            v_sync_reg <= v_sync_next;
            h_sync_reg <= h_sync_next;
         end

   // mod-2 circuit to generate 25 MHz enable tick
   assign mod2_next = ~mod2_reg;
   assign pixel_tick = mod2_reg;

   // status signals
   // end of horizontal counter (799)
   assign h_end = (h_count_reg==(HD+HF+HB+HR-1));
   // end of vertical counter (524)
   assign v_end = (v_count_reg==(VD+VF+VB+VR-1));

   // next-state logic of mod-800 horizontal sync counter
//   always @ (Master_clk) // or pixel_tick or h_end or h_count_reg) // *
   always @ (Master_clk or pixel_tick or h_end or h_count_reg) // *
      if (pixel_tick)  // 25 MHz pulse
         if (h_end)
            h_count_next = 0;
         else
            h_count_next = h_count_reg + 1;
      else
         h_count_next = h_count_reg;

   // next-state logic of mod-525 vertical sync counter
//   always @ (Master_clk) // or pixel_tick or h_end or v_end or v_count_reg) // *
   always @ (Master_clk or pixel_tick or h_end or v_end or v_count_reg) // *
      if (pixel_tick & h_end)
         if (v_end)
            v_count_next = 0;
         else
            v_count_next = v_count_reg + 1;
      else
         v_count_next = v_count_reg;

   // horizontal and vertical sync, buffered to avoid glitch
   // h_sync_next asserted between 656 and 751
   assign h_sync_next = (h_count_reg>=(HD+HB) &&
                         h_count_reg<=(HD+HB+HR-1));
   // vh_sync_next asserted between 490 and 491
   assign v_sync_next = (v_count_reg>=(VD+VB) &&
                         v_count_reg<=(VD+VB+VR-1));

   // video on/off
   assign video_on = (h_count_reg<HD) && (v_count_reg<VD);

   // output
   assign hsync = h_sync_reg;
   assign vsync = v_sync_reg;
   assign pixel_x = h_count_reg;
   assign pixel_y = v_count_reg;
   assign p_tick = pixel_tick;

   reg [7:0] rgb_next8;
   always @ (Master_clk or video_on or pre_RGB) // *
      if (~video_on) // if this blanking not done, no display is possible
         rgb_next8 = 8'b0;       // does     blank all 8 bits
      // rgb_next8 = "00000000"; // does not blank all 8 bits, don't use
      else
         rgb_next8 = pre_RGB;
   always @(posedge Master_clk)  // if not done this way, text is very fuzzy
      if (pixel_tick)
         RGB <= rgb_next8;

endmodule
